using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 文章管理接口
    /// 提供文章的增删改查、发布、置顶、推荐等功能的 RESTful API
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class ArticlesController : ControllerBase
    {
        private readonly IArticleAppService _articleService;
        private readonly ILogger<ArticlesController> _logger;

        public ArticlesController(
            IArticleAppService articleService,
            ILogger<ArticlesController> logger)
        {
            _articleService = articleService;
            _logger = logger;
        }

        /// <summary>
        /// 分页获取文章列表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="keyword">关键字</param>
        /// <param name="categoryId">分类ID</param>
        /// <param name="status">状态</param>
        /// <param name="isSticky">是否置顶</param>
        [HttpGet]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<ArticleDto>>> GetPaged(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20,
            [FromQuery] string? keyword = null,
            [FromQuery] long? categoryId = null,
            [FromQuery] byte? status = null,
            [FromQuery] bool? isSticky = null)
        {
            try
            {
                var (items, total) = await _articleService.GetPagedAsync(pageIndex, pageSize, keyword, categoryId, status, isSticky);
                var result = new PagedResultDto<ArticleDto>(items, total, pageIndex, pageSize);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting paged articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取全部文章（不分页）
        /// </summary>
        [HttpGet("all")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ArticleDto>>> GetAll()
        {
            try
            {
                var result = await _articleService.GetAllAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting all articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 按ID获取文章
        /// </summary>
        [HttpGet("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<ArticleDto>> GetById(long id)
        {
            try
            {
                var result = await _articleService.GetByIdAsync(id);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 按别名获取文章
        /// </summary>
        [HttpGet("slug/{slug}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<ArticleDto>> GetBySlug(string slug)
        {
            try
            {
                var result = await _articleService.GetBySlugAsync(slug);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting article by slug {Slug}", slug);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 检查别名是否存在
        /// </summary>
        [HttpGet("slug-exists")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<object>> SlugExists([FromQuery] string slug, [FromQuery] long? excludeId = null)
        {
            try
            {
                var exists = await _articleService.SlugExistsAsync(slug, excludeId);
                return Ok(new { exists });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking slug exists {Slug}", slug);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 按分类获取文章列表
        /// </summary>
        [HttpGet("category/{categoryId:long}")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ArticleDto>>> GetByCategory(long categoryId)
        {
            try
            {
                var result = await _articleService.GetByCategoryAsync(categoryId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting articles by category {CategoryId}", categoryId);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取置顶文章
        /// </summary>
        [HttpGet("sticky")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ArticleDto>>> GetSticky([FromQuery] int count = 10)
        {
            try
            {
                var result = await _articleService.GetStickyArticlesAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting sticky articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取最新文章
        /// </summary>
        [HttpGet("latest")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ArticleDto>>> GetLatest([FromQuery] int count = 10)
        {
            try
            {
                var result = await _articleService.GetLatestArticlesAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting latest articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取热门文章
        /// </summary>
        [HttpGet("popular")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<ArticleDto>>> GetPopular([FromQuery] int count = 10)
        {
            try
            {
                var result = await _articleService.GetPopularArticlesAsync(count);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting popular articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 搜索文章
        /// </summary>
        [HttpGet("search")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<ArticleDto>>> Search(
            [FromQuery] string keyword,
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20)
        {
            try
            {
                var (items, total) = await _articleService.SearchAsync(keyword, pageIndex, pageSize);
                var result = new PagedResultDto<ArticleDto>(items, total, pageIndex, pageSize);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error searching articles with keyword {Keyword}", keyword);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 创建文章
        /// </summary>
        [HttpPost]
        [ProducesResponseType(201)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<ArticleDto>> Create([FromBody] ArticleDto dto)
        {
            try
            {
                var created = await _articleService.CreateAsync(dto);
                return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating article");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新文章
        /// </summary>
        [HttpPut("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<ArticleDto>> Update(long id, [FromBody] ArticleDto dto)
        {
            try
            {
                dto.Id = id;
                var updated = await _articleService.UpdateAsync(dto);
                return Ok(updated);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 删除文章
        /// </summary>
        [HttpDelete("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<object>> Delete(long id)
        {
            try
            {
                var ok = await _articleService.DeleteAsync(id);
                if (!ok) return NotFound();
                return Ok(new { success = true });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 批量删除文章
        /// </summary>
        [HttpPost("batch-delete")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> BatchDelete([FromBody] BatchDeleteRequest request)
        {
            try
            {
                var count = await _articleService.BatchDeleteAsync(request.Ids);
                return Ok(new { success = true, count });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch deleting articles");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新文章状态
        /// </summary>
        [HttpPost("{id:long}/status")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> UpdateStatus(long id, [FromQuery] byte status)
        {
            try
            {
                var ok = await _articleService.UpdateStatusAsync(id, status);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating article status {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 发布文章
        /// </summary>
        [HttpPost("{id:long}/publish")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> Publish(long id)
        {
            try
            {
                var ok = await _articleService.PublishAsync(id);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error publishing article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 取消发布文章
        /// </summary>
        [HttpPost("{id:long}/unpublish")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> Unpublish(long id)
        {
            try
            {
                var ok = await _articleService.UnpublishAsync(id);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error unpublishing article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 设置置顶状态
        /// </summary>
        [HttpPost("{id:long}/sticky")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<object>> SetSticky(long id, [FromQuery] bool isSticky)
        {
            try
            {
                var ok = await _articleService.SetStickyAsync(id, isSticky);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error setting sticky for article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 增加阅读量
        /// </summary>
        [HttpPost("{id:long}/views/increment")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        [AllowAnonymous]
        public async Task<ActionResult<object>> IncrementViews(long id)
        {
            try
            {
                var ok = await _articleService.IncrementViewCountAsync(id);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error incrementing views for article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 增加点赞数
        /// </summary>
        [HttpPost("{id:long}/likes/increment")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        [AllowAnonymous]
        public async Task<ActionResult<object>> IncrementLikes(long id)
        {
            try
            {
                var ok = await _articleService.IncrementLikeCountAsync(id);
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error incrementing likes for article {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }
    }
}
